import { Injectable, forwardRef, Inject } from '@nestjs/common';
import { WX } from './wx';
import { wxConfig } from 'src/config/weixin';
import { Utils } from '../../util/utils.service';
const moment = require('moment');
import { Qrcode } from './enum';

let notify =
  process.env.NODE_ENV == 'production'
    ? 'http://106.15.50.50:3001/apitest/'
    : 'http://106.15.50.50:3001/apitest/';

//分享类型枚举
enum shareQrcodType {
  clientUserFans = 0,
}

@Injectable()
export class WxApi extends WX {
  private readonly appid: string;

  private readonly secret: string;

  private readonly public_appid: string;

  private readonly public_secret: string;

  public businessAccessTokenKey: string;

  public clientUserAccessTokenKey: string;

  public publicAccessTokenKey: string;

  constructor(
    @Inject(forwardRef(() => Utils))
    public readonly utils: Utils,
  ) {
    super(wxConfig.mch.mch_id, wxConfig.mch.key);
    this.appid = wxConfig.clientUser.appid;
    this.secret = wxConfig.clientUser.secret;
    this.public_appid = wxConfig.public.appid;
    this.public_secret = wxConfig.public.secret;
    this.clientUserAccessTokenKey = wxConfig.clientUser.AccessToken;
    this.publicAccessTokenKey = wxConfig.public.AccessToken;
  }

  /**
   * @description: 获取用户access_token
   * @param {type}
   * @return:
   */
  public async getclientUserAccessToken(): Promise<any> {
    return super.setAccessToken(
      this.appid,
      this.secret,
      this.clientUserAccessTokenKey,
    );
  }

  /**
   * @description: 获取公众号
   * @param {type}
   * @return:
   */
  public async getPublcAccessToken(): Promise<any> {
    return super.setAccessToken(
      this.public_appid,
      this.public_secret,
      this.publicAccessTokenKey,
    );
  }

  /**
   * @description: 获取用户推广小程序二维码
   * @param {number} id 用户id
   * @param {string} accessToken accessToken
   * @return: 分享二维码 buffer
   */
  public async getClientUserQrcode(
    openid: string,
    accessToken: string,
  ): Promise<string> {
    let qrcodeMap: Map<string, string | number> = new Map();
    qrcodeMap.set('type', shareQrcodType.clientUserFans);
    qrcodeMap.set('parentOpenid', openid);
    const qrcodeBuffer: Buffer = await super.qrcode(
      '/pages/index',
      accessToken,
      Qrcode.WXQRCODE,
      qrcodeMap,
    );
    const filePath: string = `qrcode/clientUserFansQrcode${openid}.jpg`;
    return await this.utils.upload(qrcodeBuffer, filePath);
  }

  /**
   * @description: 用户端小程序支付统一下单
   * @param {string|number} out_trade_no 商户订单号
   * @param {number} total_fee 标价金额（单位元）
   * @param {string} spbill_create_ip 终端IP
   * @param {string} openid
   * @return:
   */
  public async wxPay(
    out_trade_no: string,
    total_fee: number,
    spbill_create_ip: string,
    openid: string,
  ): Promise<any> {
    console.log(`回调地址：${notify}order/payNotify`, total_fee, openid);
    return super.appWxPay(
      this.appid,
      'buyGoods',
      out_trade_no,
      total_fee,
      spbill_create_ip,
      `${notify}order/payNotify`,
      openid,
    );
  }

  /**
   * @description: 企业付款到零钱
   * @param {string|number} partner_trade_no 商户订单号
   * @param {number} amount 标价金额（单位元）
   * @param {string} openid
   * @return:
   */
  public async transfers(
    partner_trade_no: string,
    openid: string,
    amount: number,
  ) {
    return super.appTransfers(
      this.appid,
      partner_trade_no,
      openid,
      amount,
      '店铺提现',
    );
  }

  /**
   * @description: 用户端小程序退款
   * @param {string|number} out_trade_no 商户订单号
   * @param {string|number} out_refund_no 退款单号
   * @param {number} total_fee 订单金额
   * @param {number} refund_fee 退款金额
   * @param {string} notify_url 退款结果通知url
   * @param {string} refund_desc 退款原因
   * @return:
   */
  public async wxRefund(
    out_trade_no: string,
    out_refund_no: string,
    total_fee: number,
    refund_fee: number,
    refund_desc?: string,
  ): Promise<any> {
    return super.refund(
      this.appid,
      out_trade_no,
      out_refund_no,
      total_fee,
      refund_fee,
      `${notify}bwx/refundNotify`,
      refund_desc,
    );
  }

  /**
   * @description: 用户端下单成功发送订单模板消息
   * @param {string} openid
   * @param {string} form_id
   * @param {string} orderCode 订单号
   * @param {Date} time 订单时间
   * @param {string} goodsName 商品名称
   * @param {number} payMoney 订单金额
   * @return:
   */
  public async orderTemplateMessage(
    openid: string,
    form_id: string,
    orderCode: string,
    time: Date,
    goodsName: string,
    payMoney: number,
  ): Promise<boolean> {
    const access_token: string = await this.getclientUserAccessToken();
    let data: Map<string, object> = new Map();
    data.set('keyword1', { value: orderCode });
    data.set('keyword2', { value: moment(time).format('YYYY-MM-DD HH:mm:ss') });
    data.set('keyword3', { value: goodsName });
    data.set('keyword4', { value: payMoney.toString() });
    const result: boolean = await super.templateMessage(
      access_token,
      openid,
      '1Q-bMa68df8YPJYFEvgWJMYGd4CDL3i9340zk4dVO18',
      '/pages/mine/order/index',
      form_id,
      data,
    );
    return result;
  }

  /**
   * @description: 公众号网页授权获取openid
   * @param {string} code
   * @return:
   */
  public async getPublicOpenid(code: string): Promise<string> {
    return await super.getPublicOpenid(
      code,
      this.public_appid,
      this.public_secret,
    );
  }
}
